package com.kc.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kc.ExceptionHandler.ClintException;
import com.kc.ExceptionHandler.UndowException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Tuple;

import java.util.Set;

/**
 * redis工具类
 */
@Component
public class RedisUtil {

    private static JedisPool jedisPool;

    @Autowired
    public void setJedisPool(JedisPool jedisPool) {
        RedisUtil.jedisPool = jedisPool;
    }

    //获取redis的实例
    public static synchronized Jedis getJedis() {
        try {
            if (jedisPool != null) {
                return jedisPool.getResource();
            }
        } catch (Exception e) {
            throw new ClintException("redis连接失败:" + e.getMessage());
        }
        return null;
    }

    public static void closePool() {
        try {
            jedisPool.close();
        } catch (Exception e) {
            throw new ClintException("释放资源失败:" + e.getMessage());
        }
    }

    /**
     * 获取object的key
     *
     * @param key
     * @return
     */
    public static Object getKey(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            ObjectMapper mapper = new ObjectMapper();
            byte[] bytes = jedis.get(key.getBytes());
            if (bytes != null) {
                return mapper.writeValueAsString(bytes);
            }
        } catch (Exception e) {
            throw new UndowException("获取key失败，请查看是否有此key");
        }
        return null;
    }

    /**
     * setObject的value
     *
     * @param key
     * @param object
     * @return
     */
    public static Object setObjectValue(String key, Object object) {
        try (Jedis jedis = jedisPool.getResource()) {
            ObjectMapper mapper = new ObjectMapper();
            return jedis.set(key.getBytes(), mapper.writeValueAsBytes(object));
        } catch (Exception e) {
            throw new UndowException("设置失败,错误信息如下" + e.getMessage());
        }
    }

    /**
     * 设置过期时间。
     *
     * @param key        主键
     * @param object     value
     * @param expiretime 过期时间，时间以毫秒为单位
     * @return
     */
    public static String setObjecttime(String key, Object object, int expiretime) {
        try (Jedis jedis = jedisPool.getResource()) {
            ObjectMapper mapper = new ObjectMapper();
            String result = jedis.set(key.getBytes(), mapper.writeValueAsBytes(object));
            if (ParamEnum.OK.equals(result)) {
                jedis.expire(key.getBytes(), expiretime);
            }
            return result;
        } catch (Exception e) {
            throw new UndowException("设置超时出错，错误如下:" + e.getMessage());
        }
    }

    /**
     * 获取key的value值
     *
     * @param key
     * @return
     */
    public static String getValue(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        } catch (Exception e) {
            throw new UndowException("获取失败，错误信息如下:" + e.getMessage());
        }
    }

    /**
     * 删除指定的键
     *
     * @param key
     * @return
     */
    public static Long KeyDel(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.del(key);
        } catch (Exception e) {
            throw new UndowException("删除失败，错误信息如下:" + e.getMessage());
        }
    }

    /**
     * 检查键是否存在
     *
     * @param key
     * @return
     */
    public static boolean exists(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.exists(key);
        } catch (Exception e) {
            throw new UndowException("检查键是否存在出错:" + e.getMessage());
        }
    }

    /**
     * 获取指定的key集合，*获取所有的key
     * h?llo will match hello hallo hhllo
     * h*llo will match hllo heeeello
     * h[ae]llo will match hello and hallo, but not hillo
     * 查看官方api文档得知的匹配规则
     *
     * @param key
     * @return
     */
    public static Set<String> Keys(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.keys(key);
        } catch (Exception e) {
            throw new UndowException("匹配出错请查看:" + e.getMessage());
        }
    }

    //制作排行的方法
    public static Long Addtop(double score, String member) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zadd("top", score, member);
        } catch (Exception e) {
            throw new UndowException("插入出错" + e.getMessage());
        }
    }


    /**
     * 第一个参数为要增加的数值
     * 第二个参数为要添加那个的用户表示。也就是文章id
     *
     * @param score
     * @param member
     * @return
     */
    public static double Addscore(double score, String member) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zincrby("top", 1, member);
        } catch (Exception e) {
            throw new UndowException("出错了" + e.getMessage());
        }
    }

    public static Set<String> getTop(long start, long end){
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.zrevrange("top",start,end);
        }catch (Exception e){
            throw new UndowException("出错了" + e.getMessage());
        }
    }
}
